#include "../../include/router/Router.h"
#include <muduo/base/Logging.h>
namespace http
{
    namespace router
    {
        // 注册对象式路由处理器
        void Router::registerHandler(const std::string &path, HttpRequest::Method method, HandlerPtr handler)
        {
            RouteKey key{method, path};
            _handlers[key] = std::move(handler);
        }
        // 注册回调函数式路由处理器
        void Router::registerCallback(const std::string &path, HttpRequest::Method method, const HandlerCallback &callback)
        {
            RouteKey key{method, path};
            _callbacks[key] = callback;
        }

        // 处理请求
        bool Router::route(const HttpRequest &request, HttpResponse &response)
        {
            RouteKey key{request.getMethod(), request.getPath()};
            // 查找对象式路由表
            auto it = _handlers.find(key);
            if (it != _handlers.end())
            {
                it->second->handle(request, response);
                return true;
            }
            // 查找回调函数式路由表
            auto callbackIt = _callbacks.find(key);
            if (callbackIt != _callbacks.end())
            {
                callbackIt->second(request, response);
                return true;
            }

            // 声明一次，供后续两个循环使用
            std::smatch match; // 用于存储匹配结果
            std::string pathStr = request.getPath();
            
            // 查找动态路由处理器，存入smatch对象，匹配成功则调用处理器
            for (const auto &[method, pathRegex, handler] : _regexHandlers)
            {
                if (method == request.getMethod() && std::regex_match(pathStr, match, pathRegex))
                {
                    HttpRequest newRequest(request);
                    extractPathParams(match, newRequest);
                    handler->handle(newRequest, response);
                    return true;
                }
            }

            // 查找正则表达式路由表，存入smatch对象，匹配成功则调用处理器
            for (const auto &[method, pathRegex, callback] : _regexCallbacks)
            {
                if (method == request.getMethod() && std::regex_match(pathStr, match, pathRegex))
                {
                    HttpRequest newRequest(request);
                    extractPathParams(match, newRequest);
                    callback(newRequest, response);
                    return true;
                }
            }
            return false;
        }

    }
}